<?php
define ('IN_ANNOUNCE', true);
include('./include/core_announce.php');
gzip();

foreach (array('passkey','info_hash','peer_id','event','ip','localip') as $x) {
	if(isset($_GET[$x])) $GLOBALS[$x] = '' . $_GET[$x];
}

foreach (array('port','downloaded','uploaded','left') as $x)
	$GLOBALS[$x] = 0+$_GET[$x];

if (strpos($passkey, '?')) {
	$tmp = substr($passkey, strpos($passkey, '?'));
	$passkey = substr($passkey, 0, strpos($passkey, '?'));
	$tmpname = substr($tmp, 1, strpos($tmp, '=')-1);
	$tmpvalue = substr($tmp, strpos($tmp, '=')+1);
	$GLOBALS[$tmpname] = $tmpvalue;
}

if ( get_magic_quotes_gpc() ) {
    $info_hash = stripslashes($info_hash);
    $peer_id = stripslashes($peer_id);
}

foreach (array('passkey','info_hash','peer_id','port','downloaded','uploaded','left') as $x) 
    if (!isset($x)) err('Missing key: '.$x);
foreach (array('info_hash','peer_id') as $x)
	if (strlen($GLOBALS[$x]) != 20)
		err('Invalid '.$x.' (' . strlen($GLOBALS[$x]) . ' - ' . urlencode($GLOBALS[$x]) . ')');
if (strlen($passkey) != 32) err('Invalid passkey (' . strlen($passkey) . ' - $passkey)');
if ( !empty($_GET['ip']) ) $ip=$_GET['ip']; else $ip = getip();

$rsize = 50;
foreach(array('num want', 'numwant', 'num_want') as $k) {
	if (isset($_GET[$k])) {
		$rsize = (int) $_GET[$k]; 
        if($rsize<0) $rsize=0;
		break;
	}
}

$agent = $_SERVER['HTTP_USER_AGENT'];

if (!$port || $port > 0xffff) err('Invalid port');
if (!isset($event)) $event = '';
$seeder = ($left == 0) ? 1 : 0;

if (function_exists('getallheaders')) $headers = getallheaders(); else $headers = emu_getallheaders();
if ( isset($headers['Cookie']) || isset($headers['Accept-Language']) || isset($headers['Accept-Charset'])) err('Anti-Cheater: You cannot use this agent');
/* banned clients */
BannedClients();
/* */
mysql_query("SELECT id FROM users WHERE passkey = " . sqlesc($passkey)) or err(mysql_error());
if (mysql_affected_rows() == 0) err('Invalid passkey! Re-download the .torrent from '.$DEFAULTBASEURL);

$hash = bin2hex($info_hash);
$res = mysql_query('SELECT id, banned, free, seeders + leechers AS numpeers, UNIX_TIMESTAMP(added) AS ts FROM torrents WHERE info_hash = "'.$hash.'"') or err(mysql_error());
$torrent = mysql_fetch_array($res);
if (!$torrent) err('Torrent not registered with this tracker.');
$torrentid = $torrent['id'];
$fields = 'seeder, peer_id, ip, port, uploaded, downloaded, userid, last_action, UNIX_TIMESTAMP(NOW()) AS nowts, UNIX_TIMESTAMP(prev_action) AS prevts';
$numpeers = $torrent['numpeers'];
$limit = '';
if ($numpeers > $rsize) $limit = ' LIMIT '.$rsize; //ORDER BY RAND() - It's not good!
$res = mysql_query('SELECT '.$fields.' FROM peers WHERE torrent = '.$torrentid.' '.$limit) or err(mysql_error());
$resp = 'd' . benc_str('interval') . 'i' . $options['announce_interval'] . 'e' . benc_str('peers') . (($compact = ($_GET['compact'] == 1)) ? '' : 'l');
$no_peer_id = ($_GET['no_peer_id'] == 1);
unset($self);
while ($row = mysql_fetch_array($res)) {
	if ($row['peer_id'] == $peer_id) {
		$userid = $row['userid'];
		$self = $row;
		continue;
	}
	if($compact) {
		$peer_ip = explode('.', $row['ip']);
		$plist .= pack("C*", $peer_ip[0], $peer_ip[1], $peer_ip[2], $peer_ip[3]). pack('n*', (int) $row['port']);
	} else {
		$resp .= 'd' .benc_str('ip') . benc_str($row['ip']) .(!$no_peer_id ? benc_str('peer id') . benc_str($row['peer_id']) : '') .benc_str('port') . 'i' . $row['port'] . 'e' . 'e';
	}
}
$resp .= ($compact ? benc_str($plist) : '') . (substr($peer_id, 0, 4) == '-BC0' ? 'e7:privatei1ee' : 'ee');
$selfwhere = 'torrent = '.$torrentid.' AND peer_id = '.sqlesc($peer_id);
if (!isset($self)) {
	$res = mysql_query('SELECT '.$fields.' FROM peers WHERE '.$selfwhere) or err(mysql_error());
	$row = mysql_fetch_array($res);
	if ($row) {
		$userid = $row['userid'];
		$self = $row;
	}
}

$announce_wait = 180;
if (isset($self)  && ($self['prevts'] > ($self['nowts'] - $announce_wait )) ) err('There is a minimum announce time of ' . $announce_wait . ' seconds');
if (!isset($self)) {
	$rz = mysql_query('SELECT id, uploaded, downloaded, class, parked, passkey_ip FROM users WHERE passkey='.sqlesc($passkey).' ORDER BY last_access DESC LIMIT 1') or err('Tracker error 2');
	if (mysql_num_rows($rz) == 0) err('Unknown passkey. Please redownload the torrent from '.$BASEURL.' - READ THE FAQ!');
	$az = mysql_fetch_array($rz);
	$userid = $az['id'];
	if ( ($az['class'] < UC_VIP ) && !empty($options['use_wait']) && !empty($numpeers) ) {
			//$gigs = $az['uploaded'] / (1024*1024*1024);
			$elapsed = floor((strtotime(date('Y-m-d H:i:s')) - $torrent['ts']) / 3600);
			$ratio = (($az['downloaded'] > 0) ? ($az['uploaded'] / $az['downloaded']) : 1);
			if ($ratio < 0.5 )
				$wait = 48;
			elseif ($ratio < 0.65 || $gigs < 6.5)
				$wait = 24;
			elseif ($ratio < 0.8 || $gigs < 8)
				$wait = 12;
			elseif ($ratio < 0.95 || $gigs < 9.5)
				$wait = 6;
			else
				$wait = 0;
			if ($elapsed < $wait) err('Not authorized (' . ($wait - $elapsed) . 'h) - READ THE FAQ!');
	}
	$passkey_ip = $az['passkey_ip'];
	if ($passkey_ip != '' && getip() != $passkey_ip) err('Unauthorized IP for this passkey!');
    } else {
	    $upthis = max(0, $uploaded - $self['uploaded']);
	    $downthis = ( ($torrent['free'] == 'yes') || ($az['class'] == UC_VIP) || ($az['class'] == UC_REDAKTOR) ) ? 0 : max(0, $downloaded - $self['downloaded']);
	    if ($az['class'] == UC_SILVER )  $downthis=intval($downthis/2);
    	if ( $upthis || $downthis ) mysql_query('UPDATE LOW_PRIORITY users SET uploaded = uploaded + '.$upthis.', downloaded = downloaded + '.$downthis.' WHERE id='.$userid) or err('Tracker error 3');
	}

$updateset = array();
$snatch_updateset = array();
if ($event == 'stopped') {
	if (isset($self)) {
	mysql_query('UPDATE LOW_PRIORITY snatched SET seeder = 0, connectable = "no" WHERE torrent = '.$torrentid.' AND userid = '.$userid) or err(mysql_error());
		mysql_query('DELETE FROM peers WHERE '.$selfwhere);
		if (mysql_affected_rows()) {
			if ( $self['seeder'] )
				$updateset[] = 'seeders = seeders - 1';
			else
				$updateset[] = 'leechers = leechers - 1';
		}
	}
} else {
	if ($event == 'completed') {
		$snatch_updateset[] = 'finished = \'yes\'';
		$snatch_updateset[] = 'completedat = NOW()';
		$snatch_updateset[] = 'seeder = 1';
		$updateset[] = 'times_completed = times_completed + 1';
	}
	if (isset($self)) {
		$downloaded2 = max(0, $downloaded - $self['downloaded']);
		$uploaded2 = max(0, $uploaded - $self['uploaded']);
		if ($downloaded2 > 0 || $uploaded2 > 0) {
			$snatch_updateset[] = "uploaded = uploaded + $uploaded2";
			$snatch_updateset[] = "downloaded = downloaded + $downloaded2";
			$snatch_updateset[] = "to_go = $left";
		}
		$snatch_updateset[] = 'port = '.$port;
		$snatch_updateset[] = 'last_action = NOW()';
		$snatch_updateset[] = 'seeder = \'$seeder\'';
		$prev_action = $self['last_action'];
		mysql_query("UPDATE LOW_PRIORITY peers SET uploaded = $uploaded, downloaded = $downloaded, uploadoffset = $uploaded2, downloadoffset = $downloaded2, to_go = $left, last_action = NOW(), prev_action = ".sqlesc($prev_action).", seeder = '$seeder'"
		. ($seeder && $self["seeder"] != $seeder ? ', finishedat = '.$_SERVER['REQUEST_TIME'] : '') . ", agent = ".sqlesc($agent)." WHERE $selfwhere") or err('Tracker error 666');
		if (mysql_affected_rows() && $self['seeder'] != $seeder) {
			if ($seeder) {
				$updateset[] = 'seeders = seeders + 1';
				$updateset[] = 'leechers = leechers - 1';
			} else {
				$updateset[] = 'seeders = seeders - 1';
				$updateset[] = 'leechers = leechers + 1';
			}
		}
	} else {
		if ($az['parked'] == 'yes') err('Error, your account is parked!');
		$res = mysql_query('SELECT torrent, userid FROM snatched WHERE torrent = '.$torrentid.' AND userid = '.$userid) or err(mysql_error());
		$check = mysql_fetch_array($res);
		if (!$check) mysql_query("INSERT LOW_PRIORITY INTO snatched (torrent, userid, port, startdat, last_action) VALUES ($torrentid, $userid, $port, NOW(), NOW())");
		$ret = mysql_query("INSERT LOW_PRIORITY INTO peers (connectable, torrent, peer_id, ip, port, uploaded, downloaded, to_go, started, last_action, seeder, userid, agent, uploadoffset, downloadoffset, passkey) VALUES ('$connectable', $torrentid, " . sqlesc($peer_id) . ", " . sqlesc($ip) . ", $port, $uploaded, $downloaded, $left, NOW(), NOW(), '$seeder', $userid, " . sqlesc($agent) . ", $uploaded, $downloaded, " . sqlesc($passkey) . ")");
		if ($ret) {
			if ($seeder) $updateset[] = 'seeders = seeders + 1';
			else $updateset[] = 'leechers = leechers + 1';
		}
	}
}
if ($seeder) {
	if ($torrent['banned'] != 'yes') $updateset[] = 'visible = \'yes\'';
	$updateset[] = 'last_action = NOW()';
}
if (count($updateset)) mysql_query('UPDATE torrents SET ' . join(', ', $updateset) . ' WHERE id = '.$torrentid);

if (count($snatch_updateset)) mysql_query('UPDATE snatched SET ' . join(', ', $snatch_updateset) . ' WHERE torrent = '.$torrentid.' AND userid = '.$userid) or err(mysql_error()."Line: ".__LINE__);

if ($_SERVER["HTTP_ACCEPT_ENCODING"] == "gzip" ) {
	header("Content-Encoding: gzip");
	echo gzencode(benc_resp_raw($resp), 9, FORCE_GZIP);
} else benc_resp_raw($resp);

?>
